- Published on
go的泛型参数如何比较大小?
- Authors
- Name
- JiGu
- @crypto20x
可比较泛型
准确的说应该叫:可排序泛型
定义一个泛型函数:
func compare[T any](a, b T){
if a > b{
...
}
}
通常用泛型的类型用any
来表示,在比较any
类型时会报错,不是所有类型都能做比较。go还提供另一个关键字comparable
,泛型类型设为comparable还是不能比较大小,它只能用于比较 ==
或者!=
是布尔型。
在go的测试版中有内置的constraints
包,将泛型设为constraints.Ordered
类型即可限制泛型的类型一定为可比较大小的类型。
在测试版中移除内置的constraints
包,在golang.org/x/exp/constraints
导入,这个属于官方实验性质的包,并不推荐使用。
type Ordered interface {
// 有符号整型,无符号整型,浮点型,和字符串可以 比较大小
Integer | Float | ~string
}
type Integer interface {
Signed | Unsigned
}
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Float interface {
~float32 | ~float64
}
在泛型中~Type
后面跟类型,~ 符号用来指定类型的基础类型 (underlying type)。当使用在接口的类型约束中,~ 表示接受的是精确这个类型或者具有相同底层类型的任何类型。
这里约束可比较的类型有:示整型,浮点型和字符串型。
Go中可比较和可排序的类型
Type | Comparable | Ordered | Description |
---|---|---|---|
Boolean | ✅ | ❌ | |
Integer | ✅ | ✅ | |
Float | ✅ | ✅ | |
Complex | ✅ | ❌ | 分别比较实数和虚数,同时相等则两个复数相等。 如果需要比较大小,需要开发者分别比较实数和虚数。 |
String | ✅ | ✅ | 基于字节逐个比较。 |
Pointer | ✅ | ❌ | 如果两个指针指向同一个对象或者都为 nil,则两者相等。 |
Channel | ✅ | ❌ | 类似 Pointer,两个 Channel 变量只有都为 nil,或者指向同一个 Channel 的时候才相等。 |
Interface | ✅ | ❌ | 两个 interface 的 Type 和 Value 值同时相等时,两者才相等。 |
Struct | ⚠️ | ❌ | 仅当 Struct 内所有成员都是 Comparable,这个 Struct 才是 Comparable 的。 如果两个 struct 类型相同,且所有非空成员变量都相等,则两者相等。 |
Array | ⚠️ | ❌ | 仅当成员为 Comparable,Array 才是 Comparable 的。 如果两个 Array 中的每一个元素一一相等时,则两个 Array 相等。 |
Map | ❌ | ❌ | |
Slice | ❌ | ❌ | |
Func | ❌ | ❌ |